package Game.Online 
{
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.Socket;
	import flash.system.Security;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	import Game.Online.Messages.Message;
	import Game.Online.Messages.MessagesDefs;
	import Game.Online.Messages.MessagesHandler;
	import Game.Windows.DebugWindow;
	/**
	 * ...
	 * @author Yevgeniy Logachev
	 */
	public class Connection extends Socket
	{		
		private var m_data:ByteArray = new ByteArray();
		private var m_id:String = "0123456789";
		private var m_dataLen:int = 0;
		
		public function Connection(host:String, port:int) 
		{
			m_data.endian = Endian.LITTLE_ENDIAN;
			endian = Endian.LITTLE_ENDIAN;
			
			//DebugWindow.instance.show = true;
			
			addEventListener(Event.CONNECT, onConnect, false, 0, true);
			addEventListener(Event.CLOSE, onClose, false, 0, true);
			addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError, false, 0, true);			
			connect(host, port);
			
			DebugWindow.instance.addLine("Create");
		}
		
		public function onConnect(e:Event):void
		{	
			DebugWindow.instance.addLine("Connect");
			addEventListener(ProgressEvent.SOCKET_DATA, onRecvData, false, 0, true);			
			OnlineManager.instance.onConnect();
		}
		
		public function onClose(e:Event):void
		{
			DebugWindow.instance.addLine("Close");
		}
		
		public function onError(e:SecurityErrorEvent):void
		{
			DebugWindow.instance.addLine("Error");
		}
		
		public function onRecvData(e:ProgressEvent):void
		{
			var i:int = 0;
			
			while (i < e.bytesLoaded)
			{
				try
				{
					m_dataLen = 0;
					m_data.clear();
					
					m_dataLen = readInt();
					i += 4;
					for (var j:int = 0; j < m_dataLen; ++j )
					{
						m_data.writeByte(readByte());
					}
					i += m_dataLen;
					
					MessagesHandler.instance.createMessage(m_data, true);
				}
				catch (error:Error)
				{
					break;
				}
			}
		}
		
		public function appendData(data:ByteArray):void
		{
			m_data.position = m_data.length;
			m_data.writeBytes(data);
		}
		
		public function handleData():void
		{
			return;
			m_data.position = 0;
			var isIncomplete:Boolean = true;
			while (m_data.position < m_data.length)
			{
				try
				{
					if (m_dataLen == 0)
					{
						if (m_data.length >= 4)
						{
							m_dataLen = m_data.readInt();
							m_data.position -= 4;
						}
						else
						{
							return;	// return if message length incomplete
						}
					}
					
					if (m_data.length >= m_dataLen + 4 && m_dataLen > 0)
					{
						isIncomplete = false;
						var buff:ByteArray = new ByteArray();
						m_data.readBytes(buff, 0, m_dataLen + 4);
						MessagesHandler.instance.createMessage(buff, true);
						m_dataLen = 0;
					}
					else
					{
						isIncomplete = true;
						return;	// return if message incomplete
					}
				}
				catch (e:Error)
				{
					trace("Error reading data");
					m_data.clear();
					m_dataLen = 0;
					return;
				}
			}
			if (!isIncomplete)
			{
				m_data.clear();
			}				
		}
		
		public function get id():String
		{
			return m_id;
		}
		
		public function sendMessage(msg:Message):void
		{
			// write msg length
			writeInt(msg.data.length);
			// write msg data
			writeBytes(msg.data);
			flush();
		}
	}
}